/*
作用：一些文件节点操作函数
作者：孙泽宇
属于mvc中的c层
*/

#include<stdio.h>
#include<stdlib.h>
#include<dos.h>
#include<dir.h>
#include<string.h>
#include<math.h>
#include"filestruct.h"
#include"svga.h"
#include"draw.h"
#include"mouse.h"
#include"putword.h"
#include"draw_item.h"
#include"input.h"
#include"disk.h"
#include"file.h"
#define N 50 //文件路径字符串大小

/*
作用：文件储存函数
输入：要储存的字符串,字符数量,文件流指针
输出：无
返回值：无
*/
void myfputs(char *s,char n,FILE *fp)
{
	char i = 0;//循环辅助变量
	while(s[i] != NULL)
	{
		fputc(s[i],fp);
		i++;
	}
	while(i <= n - 1)
	{
		fputc(' ',fp);
		i++;
	}
	return;
}

/*
作用：文件读入函数
输入：存储的字符串
输出：无
返回值：无
*/
void myfgets(char *s,char n,FILE *fp)
{
	char i = 0;//循环辅助变量
	s[0] = fgetc(fp);
	while((s[i] != ' ') && (i < n))
	{
		s[++i] = fgetc(fp);
	}
	while(i < n - 1)
	{
		fgetc(fp);
		s[i++] = NULL;
	}
	s[i] = NULL;
	return;
}

/*
作用：修改最后操作时间
输入：文件节点
输出：无
返回值：无
*/
void change_time(file_node *node)
{
	int handle;//文件句柄
	struct find_t *f;
	f = (struct find_t*)malloc(sizeof(struct find_t));
	if(f == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_ft(f);
	handle = _dos_findfirst(node->file.name,0xff,f);
	if(handle == -1)
	{
		printf("change_time");
		return;
	}
	f->wr_time = f->wr_time & 65504;
	node->file.time = node->file.time & 31;
	node->file.time = node->file.time | f->wr_time;
	node->file.date = f->wr_date;
	free(f);
	return;
}

/*
作用：修改文件大小
输入：文件节点
输出：无
返回值：无
*/
void change_size(file_node *node)
{
	int handle;//文件句柄
	struct find_t *f;
	f = (struct find_t*)malloc(sizeof(struct find_t));
	if(f == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_ft(f);
	handle = _dos_findfirst(node->file.name,0xff,f);
	if(handle == -1)
	{
		printf("change_size");
		return;
	}
	node->file.size = f->size;
	free(f);
	return;
}

/*
作用：查找文件路径
输入：文件节点,磁盘根节点,储存文件路径的指针
输出：无
返回值：无
*/
void search_nodepath(file_node *node,char *s)
{
	char i = 0;//循环辅助变量
	char j = 0;//循环辅助变量
	file_node *p;
	char **a;
	a = (char **)malloc(5*sizeof(char *));
	if(a == NULL)
	{
		printf("memory1");
		exit(1);
	}
	p = node;
	for(j = 0; j < N; j++)//初始化
	{
		s[j] = 0;
	}
	if((p->pre->file.type & 8) == 8)
	{	
		strcpy(s,"C:\\");
		free(a);
		a = NULL;
		return;
	}
	while((p->pre != NULL) && ((p->pre->file.type & 8) != 8))
	{
		while((p->pre != NULL) && ((p->file.type & 32) != 32))//让p为链表头
		{
			p = p->pre;
		}
		if(p->pre == NULL)//如果为c盘
		{
			break;
		}
		p = p->pre;//上一级文件夹
		a[i] = p->file.name;
		i++;//记录层数
	}
	i--;//减去最后++
	if(i == -1)
	{
		printf("wrong node");
		free(a);
		a = NULL;
		return;
	}
	strcpy(s,"C:\\");
	i--;//去掉c盘
	if(i == -1)
	{
		free(a);
		a = NULL;
		return;
	}
	for(;i >= 0; i--)
	{
		strcat(s,a[i]);
		strcat(s,"\\");
	}
	free(a);
	a = NULL;
	return;
}

/*
作用：修改文件名为**(i).*
输入：字符串,i
输出：无
返回值：无
*/
void change_name(char *name,char i)
{
	char j = 0;	//循环辅助变量
	char temp[13];//临时字符串
	for(j = 0;j < 13; j++)//初始化
	{
		temp[j] = '\0';
	}
	j = 0;
	while(name[j] != '.')
	{
		j++;
	}
	if(i > 5)	//文件名过长
	{
		for(j = 0; j < 5; i++)
		{
			temp[j] = name[j];
		}
		temp[j+1] = '~';
		temp[j+2] = '(';
		temp[j+3] = '0' + i;
		temp[j+4] = ')';
		i = j + 5;
		while(name[j] != '.')
		{
			j++;
		}
		while(name[j] != '\0')
		{
			temp[i] = name[j];
			i++;
			j++;
		}
	}
	strcpy(name,temp);
}

/*
作用：文件将文件设置为剪切状态(同一时间只能有一个节点处于剪切状态)
输入：文件节点,磁盘根节点
输出：无
返回值：无
*/
void file_cut_set(file_node *node,file_node *root)
{
	int head = 0;	//记录队首位置
	int tail = 0;	//记录队尾位置
	file_node **a;	//队列
	file_node *p;	//辅助指针
	a = (file_node **)malloc(100*sizeof(file_node *));
	if(a == NULL)
	{
		printf("memory");
		exit(1);
	}
	a[tail++] = root;
	while(head < tail)
	{
		p = a[head++];
		if((p->file.type & 64) == 64)
		{
			p->file.type = p->file.type ^ 64;
			break;
		}
		if((p->child != NULL) && ((p->child->file.type & 2) == 2))
		{
			a[tail++] = p->child;
		}
		if(p->next != NULL)
		{
			a[tail++] = p->next;
		}
	}
	free(a);
	node->file.type = node->file.type | 64;
}

/*
作用：文件剪切
输入：文件节点和剪切处目录
输出：无
返回值：无
*/
void file_cut(file_node *node1,file_node *node2)
{
	char i = 0;	//记录重名个数
	char old_add[N];	//记录原地址
	char new_add[N];	//记录新地址
	file_node *temp;	//用于遍历
	/* 初始化 */
	for(i = 0; i < N; i++)
	{
		old_add[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		new_add[i] = '\0';
	}
	i = 0;
	search_nodepath(node1,old_add);
	chdir(old_add);
	change_time(node1);
	search_nodepath(node2,new_add);
	strcat(old_add,node1->file.name);
	strcat(new_add,node2->file.name);
	strcat(new_add,"\\");
	temp = node2->child;
	while(temp != NULL)//有重名
	{
		if(strcmp(temp->file.name,node1->file.name) == 0)
		{
			i++;
		}
		temp = temp->next;
	}
	if(i != 0)
	{
		change_name(node1->file.name,i);
	}
	strcat(new_add,node1->file.name);
	rename(old_add,new_add);
	node1->file.type = node1->file.type ^ 64;
	if((node1->file.type & 32) == 32)		//原节点的删除
	{
		node1->pre->child = node1->next;
		node1->next->pre = node1->pre;
		node1->file.type = node1->file.type ^ 32;
		node1->next->file.type = node1->next->file.type | 32;
	}
	else
	{
		node1->pre->next = node1->next;
		node1->next->pre = node1->pre;
	}
	if(node2->child == NULL)
	{
		node2->child = node1;
		node1->pre = node2;
		node1->next = NULL;
		node1->file.type = node1->file.type | 32;
	}
	else
	{
		temp = node2->child;
		while(temp->next != NULL)
		{
			temp = temp->next;
		}
		temp->next = node1;
		node1->pre = temp;
		node1->next = NULL;
		node_sort_type(node2);	//节点按类型排序
	}
	/*以下实现层级的更新*/
	if((node2->file.time & 1) == 1)
	{
		node1->file.time = node1->file.time & 65504;
		node1->file.time = node1->file.time | 2;
	}
	if((node2->file.time & 2) == 2)
	{
		node1->file.time = node1->file.time & 65504;
		node1->file.time = node1->file.time | 4;
	}
	if((node2->file.time & 4) == 4)
	{
		node1->file.time = node1->file.time & 65504;
		node1->file.time = node1->file.time | 8;
	}
	if((node2->file.time & 8) == 8)
	{
		node1->file.time = node1->file.time & 65504;
		node1->file.time = node1->file.time | 16;
	}
	if((node2->file.time & 16) == 16)
	{
		node1->file.time = node1->file.time & 65504;//最多储存5个层级
	}
	return;
}

/*
作用：节点排序(类型，只区分目录和文件)
输入：链表头
输出：无
返回值：无
*/
void node_sort_type(file_node *head)
{
	file_node *temp;//辅助节点1
	file_node *p;	//辅助节点2
	file_node *t;	//辅助节点3
	file_node *q;	//辅助节点4
	temp = head;
	p = head->child;
	while((p->file.type & 2) == 2)
	{
		temp = p;
		p = p->next;
	}
	while(1)
	{
		while((p->file.type & 1) == 1)
		{
			if(p->next == NULL)
			{
				return;
			}
			q = p;
			p = p->next;
		}
		if(p->next != NULL)
		{
			q->next = p->next;
			p->next->pre = q;
			t = temp->next;
			temp->next = p;
			p->pre = temp;
			temp = p;
			p->next = t;
			t->pre = p;
			p = q->next;
		}
		else
		{
			q->next =  NULL;
			t = temp->next;
			temp->next = p;
			p->pre = temp;
			p->next = t;
			t->pre = p;
			return;
		}
	}
}

/*
作用：文件重命名
输入：文件对应节点,其他接口用于input_method
输出：无
返回值：无
*/
void file_rename(file_node *node,int l,int x,int y,int w,int h)
{
	char i = 0;//循环辅助变量
	char s[13];	//用于储存名字
	char old_add[N];
	char new_add[N];
	for(i = 0; i < 13; i++)
	{
		s[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		old_add[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		new_add[i] = '\0';
	}
	i = 0;
	search_nodepath(node,old_add);
	chdir(old_add);
	strcpy(new_add,old_add);
	strcat(old_add,node->file.name);
	//input_method(s,l,x,y,w,h);
	strcpy(node->file.name,s);
	strcat(new_add,s);
	rename(old_add,new_add);
}

/*
作用：将文件大小4个字节转换成字符串储存
输入：long,char*
输出：无
返回值：无
*/
void longtochar(long size,char *s)
{
	s[0] = (char)(size>>24);
	s[1] = (char)((size<<8)>>24);
	s[2] = (char)((size<<16)>>24);
	s[3] = (char)((size<<24)>>24);
}

/*
作用：将字符串转换回long
输入：long，char*
输出：无
返回值：无
*/
void chartolong(long *size,char *s)
{
	*size = 0;
	*size = *size | s[3];
	*size = *size << 8;
	*size = *size | s[2];
	*size = *size << 8;
	*size = *size | s[1];
	*size = *size << 8;
	*size = *size | s[0];
}

/*
作用：文件删除进入回收站(一次操作最多5个节点)
输入：文件节点
输出：无
返回值：无
*/
void delete_node(file_node *node1,file_node *node2,file_node *node3,file_node *node4,file_node *node5)
{
	char i = 0;//循环辅助变量
	char a[5];	//储存size
	char path[N];
	FILE *fp;
	for(i = 0; i < 5; i++)
	{
		a[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	i = 0;
	chdir("C:\\hanziku\\");
	fp = fopen("delete.txt","at+");
	if(fp == NULL)
	{
		printf("delete_list");
		return;
	}
	if(node1 != NULL)
	{
		longtochar(node1->file.size,a);
		myfputs(node1->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		search_nodepath(node1,path);
		myfputs(path,N,fp);
		change_type_hidden(node1);
		change_type_system(node1);
	}
	if(node2 != NULL)
	{
		longtochar(node2->file.size,a);
		myfputs(node2->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		search_nodepath(node2,path);
		myfputs(path,N,fp);
		change_type_hidden(node2);
		change_type_system(node2);
	}
	if(node3 != NULL)
	{
		longtochar(node3->file.size,a);
		myfputs(node3->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		search_nodepath(node3,path);
		myfputs(path,N,fp);
		change_type_hidden(node3);
		change_type_system(node3);
	}
	if(node4 != NULL)
	{
		longtochar(node4->file.size,a);
		myfputs(node4->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		search_nodepath(node4,path);
		myfputs(path,N,fp);
		change_type_hidden(node4);
		change_type_system(node4);
	}
	if(node5 != NULL)
	{
		longtochar(node5->file.size,a);
		myfputs(node5->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		search_nodepath(node2,path);
		myfputs(path,N,fp);
		change_type_hidden(node5);
		change_type_system(node5);
	}
	fclose(fp);
	return;
}

/*
作用：回收站撤回删除
输入：文件节点
输出：无
返回值：无
*/
void withdraw_delete(file_node *node)
{
	char name[13];
	char size[5];
	char pa[N];
	FILE *fp1;
	FILE *fp2;		//新文件，用来替换原文件
	char i = 0;//循环辅助变量
	for(i = 0; i < 13; i++)
	{
		name[i] = '\0';
	}
	for(i = 0; i < 5; i++)
	{
		size[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		pa[i] = '\0';
	}
	i = 0;
	chdir("C:\\hanziku\\");
	fp1 = fopen("delete.txt","at+");
	fp2 = fopen("deletet.txt","at+");
	if(fp1 == NULL)
	{
		printf("withdraw_delete1");
		exit(1);
	}
	if(fp2 == NULL)
	{
		printf("withdraw_delete2");
		exit(1);
	}
	rewind(fp1);
	myfgets(name,13,fp1);
	myfgets(size,5,fp1);
	myfgets(pa,N,fp1);
	while(feof(fp1) == 0)
	{
		if(strcmp(name,node->file.name) != 0)
		{
			myfputs(name,13,fp2);
			myfputs(size,5,fp2);
			myfputs(pa,N,fp2);
		}
		myfgets(name,13,fp1);
		myfgets(size,5,fp1);
		myfgets(pa,N,fp1);
	}
	change_type_reh(node);
	change_type_res(node);
	fclose(fp1);
	fclose(fp2);
	chdir("C:\\hanziku\\");
	unlink("delete.txt");
	rename("deletet.txt","delete.txt");
	return;
}

/*
作用：回收站文件彻底删除
输入：文件节点
输出：无
返回值：无
*/
void delete_completely(file_node *node)//广度优先算法(层次遍历)
{
	char name[13];
	char size[5];
	char pa[N];
	char path[N];//储存文件路径
	FILE *fp1;
	FILE *fp2;
	int head = 0;	//记录队首位置
	int tail = 0;	//记录队尾位置
	file_node **a;	//队列
	file_node *p;	//辅助指针
	char i = 0;//循环辅助变量
	for(i = 0; i < 13; i++)
	{
		name[i] = '\0';
	}
	for(i = 0; i < 5; i++)
	{
		size[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		pa[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	i = 0;
	a = (file_node **)malloc(20*sizeof(file_node *));
	if(a == NULL)
	{
		printf("memory");
		exit(1);
	}
	a[tail++] = node->child;//node为文件夹
	search_nodepath(node,path);
	chdir("C:\\hanziku\\");
	fp1 = fopen("delete.txt","at+");
	fp2 = fopen("deletet.txt","at+");
	if(fp1 == NULL)
	{
		printf("delete_com1");
		return;
	}
	if(fp2 == NULL)
	{
		printf("delete_com2");
		return;
	}
	rewind(fp1);
	myfgets(name,13,fp1);
	myfgets(size,5,fp1);
	myfgets(pa,N,fp1);
	while(feof(fp1) == 0)
	{
		if(strcmp(name,node->file.name) != 0)
		{
			myfputs(name,13,fp2);
			myfputs(size,5,fp2);
			myfputs(pa,N,fp2);
		}
		myfgets(name,13,fp1);
		myfgets(size,5,fp1);
		myfgets(pa,N,fp1);
	}
	fclose(fp1);
	fclose(fp2);
	chdir("C:\\hanziku\\");
	unlink("delete.txt");
	rename("deletet.txt","delete.txt");
	chdir(path);
	if((node->file.type & 32) == 32)//子链表表头
	{
		node->pre->child = node->next;
		node->next->pre = node->pre;
		node->file.type = node->file.type ^ 32;
		node->next->file.type = node->next->file.type | 32;
	}
	else
	{
		node->pre->next = node->next;
		node->next->pre = node->pre;
	}
	if((node->file.type & 2) == 2)
	{
		if(node->child != NULL)
		{
			while(head < tail)
			{
				p = a[head++];
				if(((p->file.type & 2) == 2) && (p->child == NULL))//空文件夹
				{
					search_nodepath(p,path);
					chdir(path);
					rmdir(p->file.name);
					i = 1;
				}
				else if((p->file.type & 1) == 1)
				{
					search_nodepath(p,path);
					chdir(path);
					unlink(p->file.name);
					i = 1;
				}
				if(p->child != NULL)
				{
					a[tail++] = p->child;
				}
				if(p->next != NULL)
				{
					a[tail++] = p->next;
				}
				if(i == 1)
				{
					free(p);
					a[head-1] = NULL;
					p = NULL;
					i = 0;
				}
			}
			for(;tail >= 0; tail--)
			{
				p = a[tail];
				if(p == NULL)
				{
					continue;
				}
				if((p->file.type & 2) == 2)
				{
					search_nodepath(p,path);
					chdir(path);
					rmdir(p->file.name);
					free(p);
					p = NULL;
				}
			}
			search_nodepath(node,path);
			chdir(path);
			rmdir(node->file.name);
		}
		else
		{
			rmdir(node->file.name);
		}
	}
	else if((node->file.type & 1) == 1)
	{
		search_nodepath(node,path);
		chdir(path);
		unlink(node->file.name);
	}
	free(a);		//释放队列内存
	free(node);//释放该节点内存
	return;
}

/*
作用：加入快速访问
输入：文件节点
输出:无
返回值：无
*/
void add_shortcut(file_node *node)
{
	char a[5];	//储存size
	char path[N];//储存路径
	FILE *fp;
	char i = 0;
	for(i = 0; i < 5; i++)
	{
		a[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	i = 0;
	chdir("C:\\hanziku\\");
	fp = fopen("shortcut.txt","at+");
	if(fp == NULL)
	{
		printf("shortcut_list");
		exit(1);
	}
	longtochar(node->file.size,a);
	search_nodepath(node,path);
	myfputs(node->file.name,13,fp);	//13字节
	myfputs(a,5,fp);//5字节
	myfputs(path,N,fp);//N字节
	fclose(fp);
	return;
}

/*
作用：删除快速访问节点
输入：文件节点
输出：无
返回值：无
*/
void delete_shortcut(file_node *node)
{
	char name[13];
	char size[5];
	char p[N];
	FILE *fp1;
	FILE *fp2;		//新文件，用来替换原文件
	char i = 0;//循环辅助变量
	for(i = 0; i < 13; i++)
	{
		name[i] = '\0';
	}
	for(i = 0; i < 5; i++)
	{
		size[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		p[i] = '\0';
	}
	i = 0;
	chdir("C:\\hanziku\\");
	fp1 = fopen("shortcut.txt","at+");
	fp2 = fopen("shortcu.txt","at+");
	if(fp1 == NULL)
	{
		printf("shortcut_delete1");
		exit(1);
	}
	if(fp2 == NULL)
	{
		printf("shortcut_delete2");
		exit(1);
	}
	rewind(fp1);			//回到文件头
	myfgets(name,13,fp1);
	myfgets(size,5,fp1);
	myfgets(p,N,fp1);
	while(feof(fp1) == 0)
	{
		if(strcmp(name,node->file.name) != 0)
		{
			myfputs(name,13,fp2);
			myfputs(size,5,fp2);
			myfputs(p,N,fp2);
		}
		myfgets(name,13,fp1);
		myfgets(size,5,fp1);
		myfgets(p,N,fp1);
	}
	fclose(fp1);
	fclose(fp2);
	chdir("C:\\hanziku\\");
	unlink("shortcut.txt");//删除旧文件
	rename("shortcu.txt","shortcut.txt");//新文件变成旧文件
	return;
}

/*
作用：历史记录记录
输入：文件节点
输出：无
返回值：无
*/
void add_history(file_node *node)
{
	char a[5];	//储存size
	char path[N];//储存路径
	FILE *fp;
	char i = 0;
	for(i = 0; i < 5; i++)
	{
		a[i] = '\0';
	}
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	chdir("C:\\hanziku\\");
	fp = fopen("history.txt","wt+");
	if(fp == NULL)
	{
		printf("add_history");
		exit(1);
	}
	longtochar(node->file.size,a);
	search_nodepath(node,path);
	myfputs(node->file.name,13,fp);	//13字节
	myfputs(a,5,fp);//5字节
	myfputs(path,N,fp);
	fclose(fp);
	return;
}

/*
作用：得到历史记录对应节点
输入：根节点
输出：无
返回值：对应节点
*/
file_node *get_historynode(file_node *root)
{
	FILE *fp;
	char name[13];
	char a[5];
	char path[N];
	long size = 0;
	file_node *p = NULL;
	for(size = 0; size < 13; size++)
	{
		name[size] = '\0';
	}
	for(size = 0; size < 5; size++)
	{
		a[size] = '\0';
	}
	for(size = 0; size < N; size++)
	{
		path[size] = '\0';
	}
	size = 0;
	chdir("C:\\hanziku\\");
	fp = fopen("history.txt","r");
	myfgets(name,13,fp);
	myfgets(a,5,fp);
	myfgets(path,N,fp);
	chartolong(&size,a);
	p = find_node(name,size,path,root);
	return p;
}

/*
作用：根据路径找到相应前一级文件夹
输入：根节点，路径
输出：无
返回值：节点
*/
file_node *find_lastnode(file_node *root,char *path)
{
	char i = 0;//循环辅助变量
	char j = 0;//循环辅助变量
	char x = 0;//防止死循环
	char a[13];//储存路径小节
	file_node *node;
	node = root;
	for(i = 0; i < 13; i++)
	{
		a[i] = '\0';
	}
	i = 3;
	while(path[i] != '\0')
	{
		for(j = 0; j < 13; j++)
		{
			a[j] = '\0';
		}
		j = 0;
		while((path[i] != '\0') && (path[i] != '\\'))
		{
			a[j] = path[i];
			i++;
			j++;
		}
		i ++;
		j = 0;
		node = node->child;
		while((strcmp(node->file.name,a) != 0) && (x < 20))
		{
			node = node->next;
			x++;
		}
		if(x >=  20)
		{
			return NULL;
		}
	}
	return node;
}

/*
作用：文件遍历
输入：文件名和size,根节点
输出：无
返回值：对应节点
*/
file_node *find_node(char *name,long size,char *path,file_node *root)
{
	file_node *p;
	p = find_lastnode(root,path);
	if(p == NULL)
	{
		return NULL;
	}
	p = p->child;
	while((p != NULL) && ((strcmp(name,p->file.name) != 0) || (size != p->file.size)))
	{
		p = p->next;
	}
	if(p == NULL)
	{
		return NULL;
	}
	return p;
}

/*
作用：新建文件(已存在则创建失败)
输入：name,目录节点
输出：无
返回值：成功返回1，失败返回0
*/
char file_create(char *name,file_node *node)
{
	int handle;//文件句柄
	int result;
	struct find_t *f1;//_dos_findfirst返回文件结构
	file_info *f2;	//文件信息
	file_node *file;
	file_node *temp;
	char path[N];
	char i = 0;
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	i = 0;
	search_nodepath(node,path);
	strcat(path,node->file.name);
	chdir(path);
	result = _dos_creatnew(name,32,&handle);
	if(result != 0)
	{
		printf("_dos_creatnew");
		return 0;
	}
	file = (file_node *)malloc(sizeof(file_node));
	if(file == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_node(file);
	f1 = (struct find_t *)malloc(sizeof(struct find_t));
	if(f1 == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_ft(f1);
	f2 = (file_info *)malloc(sizeof(file_info));
	if(f2 == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_info(f2);
	/*找到该文件并加入树*/
	handle = _dos_findfirst(name,0xff,f1);
	translate_filestruct(f1,f2);
	file->file = *f2;
	file->file.type = 1;
	//文件层级录入
	if((node->file.time & 1) == 1)
	{
		file->file.time = file->file.time & 65504;
		file->file.time = file->file.time | 2;
	}
	if((node->file.time & 2) == 2)
	{
		file->file.time = file->file.time & 65504;
		file->file.time = file->file.time | 4;
	}
	if((node->file.time & 4) == 4)
	{
		file->file.time = file->file.time & 65504;
		file->file.time = file->file.time | 8;
	}
	if((node->file.time & 8) == 8)
	{
		file->file.time = file->file.time & 65504;
		file->file.time = file->file.time | 16;
	}
	if((node->file.time & 16) == 16)
	{
		file->file.time = file->file.time & 65504;//最多储存5个层级
	}
	//加入树
	if(node->child == NULL)
	{
		node->child = file;
		file->file.type = file->file.type | 32;
		file->pre = node;
	}
	else
	{
		temp = node->child;
		while(temp->next != NULL)
		{
			temp = temp->next;
		}
		temp->next = file;
		file->pre = temp;
	}
	free(f1);
	free(f2);
	return 1;
}

/*
作用：新建文件夹(已存在则创建失败)
输入：name,目录节点
输出：无
返回值：成功返回1，失败返回0
*/
char dir_create(char *name,file_node *node)
{
	int handle;	//句柄
	struct find_t *f1;	//_dos_findfirst返回文件结构
	file_info *f2;	//自定义文件信息
	file_node *dir;	//新建文件节点
	file_node *temp;//辅助指针
	char path[N];
	char i = 0;
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	i = 0;
	search_nodepath(node,path);
	strcat(path,node->file.name);
	strcat(path,"\\");
	chdir(path);
	handle = mkdir(name);
	if(handle == -1)
	{
		perror("mkdir");
		return 0;
	}
	f1 = (struct find_t *)malloc(sizeof(struct find_t));
	if(f1 == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_ft(f1);
	f2 = (file_info *)malloc(sizeof(file_info));
	if(f2 == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_info(f2);
	dir = (file_node *)malloc(sizeof(file_node));
	if(dir == NULL)
	{
		printf("memory");
		exit(1);
	}
	malloc_init_node(dir);
	//下面加入新建文件节点
	handle = _dos_findfirst(name,0xff,f1);
	translate_filestruct(f1,f2);
	dir->file = *f2;
	dir->file.type = 2;
	//文件层级录入
	if((node->file.time & 1) == 1)
	{
		dir->file.time = dir->file.time & 65504;
		dir->file.time = dir->file.time | 2;
	}
	if((node->file.time & 2) == 2)
	{
		dir->file.time = dir->file.time & 65504;
		dir->file.time = dir->file.time | 4;
	}
	if((node->file.time & 4) == 4)
	{
		dir->file.time = dir->file.time & 65504;
		dir->file.time = dir->file.time | 8;
	}
	if((node->file.time & 8) == 8)
	{
		dir->file.time = dir->file.time & 65504;
		dir->file.time = dir->file.time | 16;
	}
	if((node->file.time & 16) == 16)
	{
		dir->file.time = dir->file.time & 65504;	//最多储存5个层级
	}
	//加入树
	if(node->child == NULL)
	{
		node->child = dir;
		dir->file.type = dir->file.type | 32;
		dir->pre = node;
	}
	else
	{
		temp = node;
		temp = temp->child;
		while(temp->next != NULL)
		{
			temp = temp->next;
		}
		temp->next = dir;
		dir->pre = temp;
		node_sort_type(node->child);
	}
	free(f1);
	free(f2);
	return 1;
}

/*
作用：文件复制(一次操作最多5个节点)
输入：文件节点
输出：无
返回值：无
*/
void add_copylist(file_node *node1,file_node *node2,file_node *node3,file_node *node4,file_node *node5)//包括文件夹内节点
{
	char a[5];	//储存size
	char path[N];//储存路径
	FILE *fp;
	char i = 0;
	for(i = 0; i < N; i++)
	{
		path[i] = '\0';
	}
	for(i = 0; i < 5; i++)
	{
		a[i] = '\0';
	}
	i = 0;
	chdir("C:\\hanziku\\");
	fp = fopen("copy.txt","wt+");
	if(fp == NULL)
	{
		printf("copy_list");
		exit(1);
	}
	if(node1 != NULL)
	{
		search_nodepath(node1,path);
		longtochar(node1->file.size,a);
		myfputs(node1->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		myfputs(path,N,fp);
	}
	if(node2 != NULL)
	{
		search_nodepath(node2,path);
		longtochar(node2->file.size,a);
		myfputs(node2->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		myfputs(path,N,fp);
	}
	if(node3 != NULL)
	{
		search_nodepath(node3,path);
		longtochar(node3->file.size,a);
		myfputs(node3->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		myfputs(path,N,fp);
	}
	if(node4 != NULL)
	{
		search_nodepath(node4,path);
		longtochar(node4->file.size,a);
		myfputs(node4->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		myfputs(path,N,fp);
	}
	if(node5 != NULL)
	{
		search_nodepath(node5,path);
		longtochar(node5->file.size,a);
		myfputs(node5->file.name,13,fp);	//13字节
		myfputs(a,5,fp);//5字节
		myfputs(path,N,fp);
	}
	fclose(fp);
	return;
}

/*
作用：在给定节点下遍历找到name对应节点(同名时返回层级靠前的)
输入：node,name
输出：无
返回值：对应节点
*/
file_node *get_node(file_node *node,char *name)
{
	file_node **a;//辅助队列
	char head = 0;
	char tail = 0;
	file_node *p;
	a = (file_node **)malloc(40*sizeof(file_node *));
	if(a == NULL)
	{
		printf("memory");
		exit(1);
	}
	for(head = 0; head < 40; head++)//初始化
	{
		a[head] = NULL;
	}
	head = 0;
	if(strcmp(name,node->file.name) == 0)
	{
		free(a);
		a = NULL;
		return node;
	}
	a[tail++] = node->child;
	while((head < tail) && (tail < 40))
	{
		p = a[head++];
		if(strcmp(p->file.name,name) == 0)
		{
			free(a);
			a = NULL;
			return p;
		}
		if(p->child != NULL)
		{
			a[tail++] = p->child;
		}
		if(p->next != NULL)
		{
			a[tail++] = p->next;
		}
	}
	if(tail >= 40)
	{
		printf("no or too deep");
		free(a);
		a = NULL;
		return NULL;
	}
	free(a);
	return NULL;
}

/*
作用：文件粘贴
输入：目的目录,磁盘根节点
输出：无
返回值：无
*/
void node_copy(file_node *node,file_node *root)
{
	char top = 0;//记录栈顶位置
	file_node **a;//栈，用于先序遍历
	FILE *fp1;//copy.txt
	FILE *fp2;//write
	FILE *fp3;//read
	char path[N];	//读取路径
	char s1[13];//读取文件name
	char s2[5];	//读取文件size
	char s3[N];//读取文件path
	long k = 0;	//储存size
	file_node *p;
	file_node *temp;
	file_node *t;
	a = (file_node **)malloc(20*sizeof(file_node *));
	if(a == NULL)
	{
		printf("memory");
		exit(1);
	}
	/*初始化*/
	for(k = 0; k < 20; k++)
	{
		a[k] = NULL;
	}
	for(k = 0; k < N; k++)
	{
		path[k] = '\0';
	}
	for(k = 0; k < 13; k++)
	{
		s1[k] = '\0';
	}
	for(k = 0; k < 5; k++)
	{
		s2[k] = '\0';
	}
	for(k = 0; k < N; k++)
	{
		s3[k] = '\0';
	}
	k = 0;
	chdir("c:\\hanziku\\");
	fp1 = fopen("copy.txt","r");
	if(fp1 == NULL)
	{
		printf("node_copy");
		exit(1);
	}
	myfgets(s1,13,fp1);
	myfgets(s2,5,fp1);
	myfgets(s3,N,fp1);
	if(feof(fp1) == 0)//if not empty
	{
		rewind(fp1);
	}
	else//empty
	{
		free(a);
		a = NULL;
		fclose(fp1);
		return;
	}
	while(feof(fp1) == 0)//while copy.txt not end
	{	
		search_nodepath(node,path);
		strcat(path,node->file.name);
		strcat(path,"\\");
		chdir(path);//turn to node dir
		myfgets(s1,13,fp1);
		myfgets(s2,5,fp1);
		myfgets(s3,N,fp1);
		chartolong(&k,s2);
		if(feof(fp1) != 0)
		{
			free(a);
			a = NULL;
			fclose(fp1);
			fclose(fp2);
			fclose(fp3);
			return;
		}
		p = find_node(s1,k,s3,root);
		if(p == NULL)
		{
			free(a);
			a = NULL;
			fclose(fp1);
			fclose(fp2);
			fclose(fp3);
			return;
		}
		if((p->file.type & 2) == 2)//先序遍历实现文件夹内文件复制
		{
			dir_create(p->file.name,node);
			if(p->child == NULL)
			{
				continue;
			}
			a[top++] = p->child;
			while(top > 0)//stack not empty
			{
				t = a[--top];
				if(t->next != NULL)
				{
					a[top++] = t->next;
				}
				if(t->child != NULL)
				{
					a[top++] = t->child;
				}
				if((t->file.type & 2) == 2)
				{
					if((t->file.type & 32) == 32)
					{
						temp = get_node(node,t->pre->file.name);
					}
					else
					{
						p = t;
						while((p->file.type & 32) != 32)
						{
							p = p->pre;
						}
						temp = get_node(node,p->pre->file.name);
					}
					dir_create(t->file.name,temp);
				}
				else if((t->file.type & 1) == 1)
				{
					if((t->file.type & 32) == 32)
					{
						temp = get_node(node,t->pre->file.name);
					}
					else
					{
						p = t;
						while((p->file.type & 32) != 32)
						{
							p = p->pre;
						}
						temp = get_node(node,p->pre->file.name);
					}
					file_create(t->file.name,temp);
					search_nodepath(temp->child,path);
					chdir(path);
					fp2 = fopen(t->file.name,"wt+");
					if(fp2 == NULL)
					{
						printf("node_copy");
						exit(1);
					}
					search_nodepath(t,path);
					chdir(path);
					fp3 = fopen(t->file.name,"r");
					if(fp3 == NULL)
					{
						printf("node_copy");
						exit(1);
					}
					for(k = 0; k < 13; k++)//s1 init
					{
						s1[k] = 0;
					}
					k = 0;
					fgets(s1,1,fp3);
					if(feof(fp3) == 0)
					{
						rewind(fp3);
					}
					while(feof(fp3) == 0)
					{
						fgets(s1,13,fp3);
						fputs(s1,fp2);
					}
					temp = temp->child;
					while(strcmp(temp->file.name,t->file.name) != 0)
					{
						temp = temp->next;
					}
					change_size(temp);
					fclose(fp2);
					fclose(fp3);
				}	
			}
			continue;
		}
		file_create(p->file.name,node);
		search_nodepath(node,path);
		strcat(path,node->file.name);
		strcat(path,"\\");
		chdir(path);
		fp2 = fopen(p->file.name,"wt+");
		if(fp2 == NULL)
		{
			printf("node_copy");
			exit(1);
		}
		search_nodepath(p,path);
		chdir(path);
		fp3 = fopen(p->file.name,"r");
		if(fp3 == NULL)
		{
			printf("node_copy");
			exit(1);
		}
		for(k = 0; k < 13; k++)//s1 init
		{
			s1[k] = 0;
		}
		k = 0;
		fgets(s1,1,fp3);
		if(feof(fp3) == 0)
		{
			rewind(fp3);
		}
		while(feof(fp3) == 0)
		{
			fgets(s1,13,fp3);
			fputs(s1,fp2);
		}
		temp = node->child;
		while(strcmp(temp->file.name,p->file.name) != 0)
		{
			temp = temp->next;
		}
		change_size(temp);
		fclose(fp2);
		fclose(fp3);
	}
	fclose(fp1);
	fclose(fp2);
	fclose(fp3);
	free(a);
	a = NULL;
	return;
}
